package org.geektimes.configuration.microprofile;

import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigValue;
import org.eclipse.microprofile.config.spi.ConfigSource;
import org.eclipse.microprofile.config.spi.Converter;
import org.geektimes.configuration.microprofile.converter.Converters;
import org.geektimes.configuration.microprofile.source.ConfigSources;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @Author: jipeng
 * @Description:
 * @Date: Created in 2021/3/19 8:47
 */
public class DefaultConfig implements Config {

    private final ConfigSources configSources;
    private final Converters converters;

    DefaultConfig(ConfigSources configSources, Converters converters) {
        this.configSources = configSources;
        this.converters = converters;
    }


    @Override
    public <T> T getValue(String propertyName, Class<T> propertyType) {
        String value = getValue(propertyName);
        //获取类型的Converter
        Converter<T> converter = doGetConverter(propertyType);
        return converter == null ? null : converter.convert(value);
    }


    protected  String getValue(String propertyName){
        String propertyValue = null;
        for (ConfigSource configSource : configSources) {
            propertyValue = configSource.getValue(propertyName);
            if (propertyValue != null) {
                break;
            }
        }
        return propertyValue;
    }


    @Override
    public ConfigValue getConfigValue(String propertyName) {

        return null;
    }

    @Override
    public <T> Optional<T> getOptionalValue(String propertyName, Class<T> propertyType) {
        T value = getValue(propertyName,propertyType);
        return value == null ? Optional.empty() : Optional.of(value);
    }

    @Override
    public Iterable<String> getPropertyNames() {
        List<String> propertyNames = new ArrayList<>();
        for(ConfigSource configSource : configSources){
            propertyNames.addAll(configSource.getPropertyNames());
        }
        return propertyNames;
    }

    @Override
    public Iterable<ConfigSource> getConfigSources() {
        return configSources;
    }

    @Override
    public <T> Optional<Converter<T>> getConverter(Class<T> forType) {
        Converter<T> converter = doGetConverter(forType);
        return converter == null ? Optional.empty() : Optional.of(converter);
    }

    protected <T> Converter<T> doGetConverter( Class<T> forType){
        List<Converter> converters = this.converters.getConverters(forType);
        return converters.isEmpty() ? null : converters.get(0);
    }

    @Override
    public <T> T unwrap(Class<T> type) {
        return null;
    }
}
